package com.android.hidephotosplus.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Scanner;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;

import com.android.hidephotosplus.R;

public class StorageInfo {
	// =======================================================================

	public static ArrayList<StorageInfo> STORAGES = new ArrayList<StorageInfo>();

	public enum STORAGETYPE {
		INTERNAL, EXTERNAL, ROOT, SYSTEM;

		public String getName(Context context) {
			switch (this) {
			case INTERNAL:
				return context.getString(R.string.internal);
			case EXTERNAL:
				return context.getString(R.string.sdcard);
			case SYSTEM:
				return context.getString(R.string.system_storage);
			default:
				return "";
			}
		}
	}

	static {
		getStorageInformation();
	}

	// =======================================================================

	public String path;
	public STORAGETYPE type;

	// =======================================================================

	private StorageInfo(String path, STORAGETYPE type) {
		this.path = path;
		this.type = type;
	}

	// =======================================================================

	public static boolean isMountable(String path) {
		for (StorageInfo storage : STORAGES) {
			if (!storage.path.equals("/") && path.startsWith(storage.path)) {
				return false;
			}
		}

		return true;
	}

	public boolean isValid() {
		File root = new File(this.path);
		return root.exists() && root.isDirectory() && root.canRead();
	}

	private static void getStorageInformation() {
		try {
			readMountsFile();
		} catch (Throwable e) {
			STORAGES.clear();
			STORAGES.add(new StorageInfo(Environment
					.getExternalStorageDirectory().getPath(),
					STORAGETYPE.EXTERNAL));
		}

		STORAGES.add(new StorageInfo("/", STORAGETYPE.ROOT));
	}

	@SuppressLint("NewApi")
	private static void readMountsFile() {
		ArrayList<String> mountPaths = new ArrayList<String>();

		String defaultSdcard = Environment.getExternalStorageDirectory()
				.getPath();
		mountPaths.add(defaultSdcard);

		try {
			Scanner scanner = new Scanner(new File("/proc/mounts"));
			while (scanner.hasNext()) {
				String line = scanner.nextLine();
				if (line.startsWith("/dev/block/vold/")) {
					String[] lineElements = line.split(" ");
					String element = lineElements[1];

					if (!element.equals(defaultSdcard)) {
						mountPaths.add(element);
					}
				}
			}
		} catch (Exception e) {
			//Logging.print(e);
		}

		if (mountPaths.size() > 0) {
			String defaultStorage = mountPaths.get(0);

			if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
				STORAGES.add(new StorageInfo(defaultStorage,
						STORAGETYPE.EXTERNAL));
			} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
				if (Environment.isExternalStorageRemovable()) {
					STORAGES.add(new StorageInfo(defaultStorage,
							STORAGETYPE.EXTERNAL));
				} else
					STORAGES.add(new StorageInfo(defaultStorage,
							STORAGETYPE.INTERNAL));
			} else {
				if (!Environment.isExternalStorageRemovable()
						|| Environment.isExternalStorageEmulated())
					STORAGES.add(new StorageInfo(defaultStorage,
							STORAGETYPE.INTERNAL));
				else {
					STORAGES.add(new StorageInfo(defaultStorage,
							STORAGETYPE.EXTERNAL));
				}
			}

			if (mountPaths.size() > 1) {
				for (int i = 1; i < mountPaths.size(); i++) {
					STORAGES.add(new StorageInfo(mountPaths.get(i),
							STORAGETYPE.EXTERNAL));
				}
			}
		}
	}

	// =======================================================================

	public static long[] getMemoryStat(Context context) {
		long[] stat = new long[3];

		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					new FileInputStream("/proc/meminfo")), 1000);
			String total = reader.readLine();
			reader.close();

			stat[0] = Long.parseLong(total.split("\\s+")[1]) * 1024;

			MemoryInfo mi = new MemoryInfo();
			ActivityManager activityManager = (ActivityManager) context
					.getSystemService(Context.ACTIVITY_SERVICE);
			activityManager.getMemoryInfo(mi);

			stat[1] = mi.availMem;
			stat[2] = stat[0] - stat[1];
		} catch (IOException ex) {

		}

		return stat;
	}

	public static long[] getSystemSpaceStat() {
		return getUsageStat(Environment.getDataDirectory().getPath());
	}

	public static long[] getSDCardStat() {
		return getUsageStat(Environment.getExternalStorageDirectory().getPath());
	}

	public static long[] getUsageStat(String path) {
		long[] stat = new long[3];
		StatFs fs = new StatFs(path);
		stat[0] = (long) fs.getBlockSize() * (long) fs.getBlockCount();
		stat[1] = (long) fs.getBlockSize() * (long) fs.getAvailableBlocks();
		stat[2] = stat[0] - stat[1];
		return stat;
	}

	// =======================================================================
}